#ifndef REGISTER_H
#define REGISTER_H

/**
* @file register.h
*
*	 Nel file register.h sono presenti le strutture, le classi e le funzioni per poter
*	 gestire efficacemente un Registro di Servizi.
*	 In questo Registro, più Service Provider, possono registrare diversi servizi.
*	 In generale diversi Service Provider possono registrare uno stesso tipo di servizio, rinosciuto univocamente
*	 nel sistema mediante il nome.
*	 Tra i vari Service Provider che registrano lo stesso servizio abbiamo implementato una politica FIFO, in cui
*	 ogni volta che arriva una richiesta da un client per un determinato servizio, il Service Register seleziona
*	 il Service Provider che da più tempo non accoglie richieste. 
*
* @author Favale Angelo
* @author Fagioli Alessio
*
* @version 1.0
*/

#include "../libreria.h"

/** Dimensione massima di una stringa di caratteri*/
#define BUFFER_SIZE 512

/**
* @param buffer Messaggio da decodificare
* @param porta Porta del Service Provider
* @param ip Ip del Service Provider
*
* @return Numero di servizi che si vuole registrare
*
* La funzione decode_msg_from_SP permette al Service Register di decodificare il messaggio
* inviato da un Service Provider per registrare i suoi servizi
*/
int decode_msg_from_SP( char * buffer, char * porta, char * ip ); 

/**
* @param name_service Nome del servizio da registrare ritornato per riferimento
* @param s identificatore del socket per la comunicazione con il Service Provider
*
* @return true se la ricezione del nome del servizio è avvenuta con successo, false 
*	  altrimenti
*
* La funzione receive_name_service permette al Service Register di ricevere il nome del
* servizio che il Service Provider vuole registrare
*/
bool receive_name_service ( char * name_service, int s );

/**
* @param buffer messaggio da decodificare
* @param nome_servizio Nome del servizio richiesto dal client ritornato per riferimento
*
* @return true se la ricezione del nome del servizio è avvenuta con successo, false 
*	  altrimenti
*
* La funzione decode_msg_from_client permette al Service Register di ricevere il nome del
* servizio richiesto dal client
*/
bool decode_msg_from_client( char * buffer, char * nome_servizio );

/**
* La struttura node mantiene le informazioni relative al Service Provider che registrato un 
* dato servizio.
*/
struct node
{
	char name_service [BUFFER_SIZE];/**< nome di un dato servizio 		   	   */
	char ip [INET_ADDRSTRLEN];  	/**< ip del Service Provider che fornisce quel dato 
					 *   servizio					   */
	int porta; 			/**< numero di porta del Service Provider che 	
					 *   fornisce quel dato servizio		   */
	node * same_service;		 /**< puntatore che indirizza il prossimo elemento 
			    		*     nella sottolista di quello specifico servizio*/
	node * next_service; 		/**< puntatore che indirizza il prossimo 
					 *   elemento nella lista principale		   */
};



/**
* @class Register
*
*	 La classe Register implementa la gestione del registro contenente i servizi messi a 
*	 disposizione dai vari Service Provider.
*	 L'implementazione di questo registro viene fatta tramite l'utilizzo di una lista 
*	 principale in cui ogni elemento a sua volta implementa un'ulteriore lista.
*/
class Register
{
	private:
		node * first; 

	public :
		/**
		* Il costrutture si preoccupa di inizializzare la lista che deve tenere
		* aggiornati i servizi messi a disposizione dai vari Service Provider
		*/
		Register ();
		
		/**
		* @param name Nome del servizio che si vuole registrare
		* @param service_provider Contiene le informazioni per indirizzare 
		*			  univocamente il Service Provider
		*
		* @return true se l'inserimento del nuovo servizio è andato a buon fine
		*
		* Questo metodo segna nel registro che il servizio name viene offerto dal
		* Service Provider identificato dalla struttura service_provider
		*/
		bool add_node (char name[], host service_provider);
		/**
		* @param name Nome del servizio da cercare
		*
		* @return Il puntatore alla struttura host che contiene informazioni su un
		* 	  Servie Provider che implementa il servizio richiesto
		*
		* Questo metodo estrae dal registro un puntatore a struttura host che
		* mantiene informazioni sul Service Provider che fornisce quel particolare
		* servizio
		*/
		host * extract_node (char name[]);
		
		/**
		* @param ip Ip del Service Provider
		* @param porta Porta del Service Provider
		* @param service Nome del servizio da cancellare
		*
		* @return true se è riuscito a cancellare dal registro il Service Provider
		*	  che forniva il servizio specificato.
		*	  In caso contrario ritorna false
		*
		* Questo metodo elimina dal registro il servizio fornito da uno specifico 
		* Service Provider, identificato da ip e porta
		*/
		bool rm_service_provider (char ip[], int porta, char service[]);
		
};

			

#endif
